#!/bin/bash

if [ ! -d "llvm-project" ]; then
  git clone https://gitee.com/mirrors/LLVM.git llvm-project
fi  
cd llvm-project
git checkout llvmorg-19-init
cd ..

TOPLEV=`pwd`

# stage1 : build native clang
if [ -d "${TOPLEV}/stage1" ]; then
  rm -fr ${TOOPLEV}/stage1
fi
mkdir ${TOPLEV}/stage1
cd ${TOPLEV}/stage1
export LDFLAGS="-Wl,-q"
cmake -G Ninja ${TOPLEV}/llvm-project/llvm -DLLVM_TARGETS_TO_BUILD="AArch64" \
      -DCMAKE_BUILD_TYPE=Release \
      -DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++ -DCMAKE_ASM_COMPILER=gcc \
      -DLLVM_ENABLE_PROJECTS="clang;lld" \
      -DLLVM_ENABLE_RUNTIMES="compiler-rt" \
      -DCOMPILER_RT_BUILD_SANITIZERS=OFF -DCOMPILER_RT_BUILD_XRAY=OFF \
      -DCMAKE_INSTALL_PREFIX=${TOPLEV}/stage1/install

ninja install -j`nproc`


# stage2 : generate perf data 
if [ -d "${TOPLEV}/stage2" ]; then
  rm -fr ${TOOPLEV}/stage2
fi
mkdir ${TOPLEV}/stage2
cd ${TOPLEV}/stage2
CPATH=${TOPLEV}/stage1/install/bin
cmake -G Ninja ${TOPLEV}/llvm-project/llvm -DLLVM_TARGETS_TO_BUILD="AArch64" \
	-DCMAKE_BUILD_TYPE=Release \
	-DCMAKE_C_COMPILER=$CPATH/clang -DCMAKE_CXX_COMPILER=$CPATH/clang++ \
	-DLLVM_USE_LINKER="lld" \
	-DLLVM_ENABLE_PROJECTS="clang" \
	-DCMAKE_INSTALL_PREFIX=${TOPLEV}/stage2/install

perf record -e cycles:u -- ninja clang -j`nproc`


# stage3 : convert perf.data to perf.fdata
perf2bolt $CPATH/clang-19 -p ${TOPLEV}/stage2/perf.data -o ${TOPLEV}/perf.fdata -w perf.yaml


# stage4 : bolt app
llvm-bolt $CPATH/clang-19 -o $CPATH/clang.bolt.perf -data=${TOPLEV}/perf.fdata -reorder-blocks=ext-tsp -reorder-functions=hfsort -split-functions -split-all-cold -split-eh -dyno-stats


# stage5 : execute actions using clang and clang.bolt.perf

if [ -d "${TOPLEV}/stage5" ]; then
  rm -fr ${TOOPLEV}/stage5
fi
mkdir ${TOPLEV}/stage5
cd ${TOPLEV}/stage5
CPATH=${TOPLEV}/stage1/install/bin
cd ${CPATH}
ln -snf clang-19 clang++
ln -snf clang-19 clang
cd -
cmake -G Ninja ${TOPLEV}/llvm-project/llvm -DLLVM_TARGETS_TO_BUILD="AArch64" \
	-DCMAKE_BUILD_TYPE=Release \
	-DCMAKE_C_COMPILER=$CPATH/clang -DCMAKE_CXX_COMPILER=$CPATH/clang++ \
	-DLLVM_ENABLE_PROJECTS="clang" \
	-DCMAKE_INSTALL_PREFIX=${TOPLEV}/stage5/install

ninja clean && time ninja clang -j`nproc`


cd ${CPATH}
ln -snf clang.bolt.perf clang++
ln -snf clang.bolt.perf clang
cd -
cmake -G Ninja ${TOPLEV}/llvm-project/llvm -DLLVM_TARGETS_TO_BUILD="AArch64" \
	-DCMAKE_BUILD_TYPE=Release \
	-DCMAKE_C_COMPILER=$CPATH/clang -DCMAKE_CXX_COMPILER=$CPATH/clang++ \
	-DLLVM_ENABLE_PROJECTS="clang" \
	-DCMAKE_INSTALL_PREFIX=${TOPLEV}/stage5/install

ninja clean && time ninja clang -j`nproc`

